home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / WarpQuake / Src / gl_warp.c < prev    next >
C/C++ Source or Header  |  2000-05-22  |  22KB  |  1,093 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // gl_warp.c -- sky and water polygons
  21.  
  22. #include "quakedef.h"
  23.  
  24. extern    model_t    *loadmodel;
  25.  
  26. int        skytexturenum;
  27.  
  28. int        solidskytexture;
  29. int        alphaskytexture;
  30. float    speedscale;        // for top sky and bottom sky
  31.  
  32. msurface_t    *warpface;
  33.  
  34. extern cvar_t gl_subdivide_size;
  35.  
  36. void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs)
  37. {
  38.     int        i, j;
  39.     float    *v;
  40.  
  41.     mins[0] = mins[1] = mins[2] = 9999;
  42.     maxs[0] = maxs[1] = maxs[2] = -9999;
  43.     v = verts;
  44.     for (i=0 ; i<numverts ; i++)
  45.         for (j=0 ; j<3 ; j++, v++)
  46.         {
  47.             if (*v < mins[j])
  48.                 mins[j] = *v;
  49.             if (*v > maxs[j])
  50.                 maxs[j] = *v;
  51.         }
  52. }
  53.  
  54. void SubdividePolygon (int numverts, float *verts)
  55. {
  56.     int        i, j, k;
  57.     vec3_t    mins, maxs;
  58.     float    m;
  59.     float    *v;
  60.     vec3_t    front[64], back[64];
  61.     int        f, b;
  62.     float    dist[64];
  63.     float    frac;
  64.     glpoly_t    *poly;
  65.     float    s, t;
  66.  
  67.     if (numverts > 60)
  68.         Sys_Error ("numverts = %i", numverts);
  69.  
  70.     BoundPoly (numverts, verts, mins, maxs);
  71.  
  72.     for (i=0 ; i<3 ; i++)
  73.     {
  74.         m = (mins[i] + maxs[i]) * 0.5;
  75.         m = gl_subdivide_size.value * floor (m/gl_subdivide_size.value + 0.5);
  76.         if (maxs[i] - m < 8)
  77.             continue;
  78.         if (m - mins[i] < 8)
  79.             continue;
  80.  
  81.         // cut it
  82.         v = verts + i;
  83.         for (j=0 ; j<numverts ; j++, v+= 3)
  84.             dist[j] = *v - m;
  85.  
  86.         // wrap cases
  87.         dist[j] = dist[0];
  88.         v-=i;
  89.         VectorCopy (verts, v);
  90.  
  91.         f = b = 0;
  92.         v = verts;
  93.         for (j=0 ; j<numverts ; j++, v+= 3)
  94.         {
  95.             if (dist[j] >= 0)
  96.             {
  97.                 VectorCopy (v, front[f]);
  98.                 f++;
  99.             }
  100.             if (dist[j] <= 0)
  101.             {
  102.                 VectorCopy (v, back[b]);
  103.                 b++;
  104.             }
  105.             if (dist[j] == 0 || dist[j+1] == 0)
  106.                 continue;
  107.             if ( (dist[j] > 0) != (dist[j+1] > 0) )
  108.             {
  109.                 // clip point
  110.                 frac = dist[j] / (dist[j] - dist[j+1]);
  111.                 for (k=0 ; k<3 ; k++)
  112.                     front[f][k] = back[b][k] = v[k] + frac*(v[3+k] - v[k]);
  113.                 f++;
  114.                 b++;
  115.             }
  116.         }
  117.  
  118.         SubdividePolygon (f, front[0]);
  119.         SubdividePolygon (b, back[0]);
  120.         return;
  121.     }
  122.  
  123.     poly = Hunk_Alloc (sizeof(glpoly_t) + (numverts-4) * VERTEXSIZE*sizeof(float));
  124.     poly->next = warpface->polys;
  125.     warpface->polys = poly;
  126.     poly->numverts = numverts;
  127.     for (i=0 ; i<numverts ; i++, verts+= 3)
  128.     {
  129.         VectorCopy (verts, poly->verts[i]);
  130.         s = DotProduct (verts, warpface->texinfo->vecs[0]);
  131.         t = DotProduct (verts, warpface->texinfo->vecs[1]);
  132.         poly->verts[i][3] = s;
  133.         poly->verts[i][4] = t;
  134.     }
  135. }
  136.  
  137. /*
  138. ================
  139. GL_SubdivideSurface
  140.  
  141. Breaks a polygon up along axial 64 unit
  142. boundaries so that turbulent and sky warps
  143. can be done reasonably.
  144. ================
  145. */
  146. void GL_SubdivideSurface (msurface_t *fa)
  147. {
  148.     vec3_t        verts[64];
  149.     int            numverts;
  150.     int            i;
  151.     int            lindex;
  152.     float        *vec;
  153.     texture_t    *t;
  154.  
  155.     warpface = fa;
  156.  
  157.     //
  158.     // convert edges back to a normal polygon
  159.     //
  160.     numverts = 0;
  161.     for (i=0 ; i<fa->numedges ; i++)
  162.     {
  163.         lindex = loadmodel->surfedges[fa->firstedge + i];
  164.  
  165.         if (lindex > 0)
  166.             vec = loadmodel->vertexes[loadmodel->edges[lindex].v[0]].position;
  167.         else
  168.             vec = loadmodel->vertexes[loadmodel->edges[-lindex].v[1]].position;
  169.         VectorCopy (vec, verts[numverts]);
  170.         numverts++;
  171.     }
  172.  
  173.     SubdividePolygon (numverts, verts[0]);
  174. }
  175.  
  176. //=========================================================
  177.  
  178.  
  179.  
  180. // speed up sin calculations - Ed
  181. float    turbsin[] =
  182. {
  183.     #include "gl_warp_sin.h"
  184. };
  185. #define TURBSCALE (256.0 / (2 * M_PI))
  186.  
  187. /*
  188. =============
  189. EmitWaterPolys
  190.  
  191. Does a water warp on the pre-fragmented glpoly_t chain
  192. =============
  193. */
  194. void EmitWaterPolys (msurface_t *fa)
  195. {
  196.     glpoly_t    *p;
  197.     float        *v;
  198.     int            i;
  199.     float        s, t, os, ot;
  200.  
  201.  
  202.     for (p=fa->polys ; p ; p=p->next)
  203.     {
  204.         glBegin (GL_POLYGON);
  205.         for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
  206.         {
  207.             os = v[3];
  208.             ot = v[4];
  209.  
  210.             s = os + turbsin[(int)((ot*0.125+realtime) * TURBSCALE) & 255];
  211.             s *= (1.0/64);
  212.  
  213.             t = ot + turbsin[(int)((os*0.125+realtime) * TURBSCALE) & 255];
  214.             t *= (1.0/64);
  215.  
  216.             glTexCoord2f (s, t);
  217.             glVertex3fv (v);
  218.         }
  219.         glEnd ();
  220.     }
  221. }
  222.  
  223.  
  224.  
  225.  
  226. /*
  227. =============
  228. EmitSkyPolys
  229. =============
  230. */
  231. void EmitSkyPolys (msurface_t *fa)
  232. {
  233.     glpoly_t    *p;
  234.     float        *v;
  235.     int            i;
  236.     float    s, t;
  237.     vec3_t    dir;
  238.     float    length;
  239.  
  240.     for (p=fa->polys ; p ; p=p->next)
  241.     {
  242.         glBegin (GL_POLYGON);
  243.         for (i=0,v=p->verts[0] ; i<p->numverts ; i++, v+=VERTEXSIZE)
  244.         {
  245.             VectorSubtract (v, r_origin, dir);
  246.             dir[2] *= 3;    // flatten the sphere
  247.  
  248.             length = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2];
  249.             length = sqrt (length);
  250.             length = 6*63/length;
  251.  
  252.             dir[0] *= length;
  253.             dir[1] *= length;
  254.  
  255.             s = (speedscale + dir[0]) * (1.0/128);
  256.             t = (speedscale + dir[1]) * (1.0/128);
  257.  
  258.             glTexCoord2f (s, t);
  259.             glVertex3fv (v);
  260.         }
  261.         glEnd ();
  262.     }
  263. }
  264.  
  265. /*
  266. ===============
  267. EmitBothSkyLayers
  268.  
  269. Does a sky warp on the pre-fragmented glpoly_t chain
  270. This will be called for brushmodels, the world
  271. will have them chained together.
  272. ===============
  273. */
  274. void EmitBothSkyLayers (msurface_t *fa)
  275. {
  276.     int            i;
  277.     int            lindex;
  278.     float        *vec;
  279.  
  280.     GL_DisableMultitexture();
  281.  
  282.     GL_Bind (solidskytexture);
  283.     speedscale = realtime*8;
  284.     speedscale -= (int)speedscale & ~127 ;
  285.  
  286.     EmitSkyPolys (fa);
  287.  
  288.     glEnable (GL_BLEND);
  289.     GL_Bind (alphaskytexture);
  290.     speedscale = realtime*16;
  291.     speedscale -= (int)speedscale & ~127 ;
  292.  
  293.     EmitSkyPolys (fa);
  294.  
  295.     glDisable (GL_BLEND);
  296. }
  297.  
  298. #ifndef QUAKE2
  299. /*
  300. =================
  301. R_DrawSkyChain
  302. =================
  303. */
  304. void R_DrawSkyChain (msurface_t *s)
  305. {
  306.     msurface_t    *fa;
  307.  
  308.     GL_DisableMultitexture();
  309.  
  310.     // used when gl_texsort is on
  311.     GL_Bind(solidskytexture);
  312.     speedscale = realtime*8;
  313.     speedscale -= (int)speedscale & ~127 ;
  314.  
  315.     for (fa=s ; fa ; fa=fa->texturechain)
  316.         EmitSkyPolys (fa);
  317.  
  318.     glEnable (GL_BLEND);
  319.     GL_Bind (alphaskytexture);
  320.     speedscale = realtime*16;
  321.     speedscale -= (int)speedscale & ~127 ;
  322.  
  323.     for (fa=s ; fa ; fa=fa->texturechain)
  324.         EmitSkyPolys (fa);
  325.  
  326.     glDisable (GL_BLEND);
  327. }
  328.  
  329. #endif
  330.  
  331. /*
  332. =================================================================
  333.  
  334.   Quake 2 environment sky
  335.  
  336. =================================================================
  337. */
  338.  
  339. #ifdef QUAKE2
  340.  
  341.  
  342. #define    SKY_TEX        2000
  343.  
  344. /*
  345. =================================================================
  346.  
  347.   PCX Loading
  348.  
  349. =================================================================
  350. */
  351.  
  352. typedef struct
  353. {
  354.     char    manufacturer;
  355.     char    version;
  356.     char    encoding;
  357.     char    bits_per_pixel;
  358.     unsigned short    xmin,ymin,xmax,ymax;
  359.     unsigned short    hres,vres;
  360.     unsigned char    palette[48];
  361.     char    reserved;
  362.     char    color_planes;
  363.     unsigned short    bytes_per_line;
  364.     unsigned short    palette_type;
  365.     char    filler[58];
  366.     unsigned     data;            // unbounded
  367. } pcx_t;
  368.  
  369. byte    *pcx_rgb;
  370.  
  371. /*
  372. ============
  373. LoadPCX
  374. ============
  375. */
  376. void LoadPCX (FILE *f)
  377. {
  378.     pcx_t    *pcx, pcxbuf;
  379.     byte    palette[768];
  380.     byte    *pix;
  381.     int        x, y;
  382.     int        dataByte, runLength;
  383.     int        count;
  384.  
  385. //
  386. // parse the PCX file
  387. //
  388.     fread (&pcxbuf, 1, sizeof(pcxbuf), f);
  389.  
  390.     pcx = &pcxbuf;
  391.  
  392.     if (pcx->manufacturer != 0x0a
  393.         || pcx->version != 5
  394.         || pcx->encoding != 1
  395.         || pcx->bits_per_pixel != 8
  396.         || pcx->xmax >= 320
  397.         || pcx->ymax >= 256)
  398.     {
  399.         Con_Printf ("Bad pcx file\n");
  400.         return;
  401.     }
  402.  
  403.     // seek to palette
  404.     fseek (f, -768, SEEK_END);
  405.     fread (palette, 1, 768, f);
  406.  
  407.     fseek (f, sizeof(pcxbuf) - 4, SEEK_SET);
  408.  
  409.     count = (pcx->xmax+1) * (pcx->ymax+1);
  410.     pcx_rgb = malloc( count * 4);
  411.  
  412.     for (y=0 ; y<=pcx->ymax ; y++)
  413.     {
  414.         pix = pcx_rgb + 4*y*(pcx->xmax+1);
  415.         for (x=0 ; x<=pcx->ymax ; )
  416.         {
  417.             dataByte = fgetc(f);
  418.  
  419.             if((dataByte & 0xC0) == 0xC0)
  420.             {
  421.                 runLength = dataByte & 0x3F;
  422.                 dataByte = fgetc(f);
  423.             }
  424.             else
  425.                 runLength = 1;
  426.  
  427.             while(runLength-- > 0)
  428.             {
  429.                 pix[0] = palette[dataByte*3];
  430.                 pix[1] = palette[dataByte*3+1];
  431.                 pix[2] = palette[dataByte*3+2];
  432.                 pix[3] = 255;
  433.                 pix += 4;
  434.                 x++;
  435.             }
  436.         }
  437.     }
  438. }
  439.  
  440. /*
  441. =========================================================
  442.  
  443. TARGA LOADING
  444.  
  445. =========================================================
  446. */
  447.  
  448. typedef struct _TargaHeader {
  449.     unsigned char     id_length, colormap_type, image_type;
  450.     unsigned short    colormap_index, colormap_length;
  451.     unsigned char    colormap_size;
  452.     unsigned short    x_origin, y_origin, width, height;
  453.     unsigned char    pixel_size, attributes;
  454. } TargaHeader;
  455.  
  456.  
  457. TargaHeader        targa_header;
  458. byte            *targa_rgba;
  459.  
  460. int fgetLittleShort (FILE *f)
  461. {
  462.     byte    b1, b2;
  463.  
  464.     b1 = fgetc(f);
  465.     b2 = fgetc(f);
  466.  
  467.     return (short)(b1 + b2*256);
  468. }
  469.  
  470. int fgetLittleLong (FILE *f)
  471. {
  472.     byte    b1, b2, b3, b4;
  473.  
  474.     b1 = fgetc(f);
  475.     b2 = fgetc(f);
  476.     b3 = fgetc(f);
  477.     b4 = fgetc(f);
  478.  
  479.     return b1 + (b2<<8) + (b3<<16) + (b4<<24);
  480. }
  481.  
  482.  
  483. /*
  484. =============
  485. LoadTGA
  486. =============
  487. */
  488. void LoadTGA (FILE *fin)
  489. {
  490.     int                columns, rows, numPixels;
  491.     byte            *pixbuf;
  492.     int                row, column;
  493.  
  494.     targa_header.id_length = fgetc(fin);
  495.     targa_header.colormap_type = fgetc(fin);
  496.     targa_header.image_type = fgetc(fin);
  497.     
  498.     targa_header.colormap_index = fgetLittleShort(fin);
  499.     targa_header.colormap_length = fgetLittleShort(fin);
  500.     targa_header.colormap_size = fgetc(fin);
  501.     targa_header.x_origin = fgetLittleShort(fin);
  502.     targa_header.y_origin = fgetLittleShort(fin);
  503.     targa_header.width = fgetLittleShort(fin);
  504.     targa_header.height = fgetLittleShort(fin);
  505.     targa_header.pixel_size = fgetc(fin);
  506.     targa_header.attributes = fgetc(fin);
  507.  
  508.     if (targa_header.image_type!=2 
  509.         && targa_header.image_type!=10) 
  510.         Sys_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
  511.  
  512.     if (targa_header.colormap_type !=0 
  513.         || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
  514.         Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
  515.  
  516.     columns = targa_header.width;
  517.     rows = targa_header.height;
  518.     numPixels = columns * rows;
  519.  
  520.     targa_rgba = malloc (numPixels*4);
  521.     
  522.     if (targa_header.id_length != 0)
  523.         fseek(fin, targa_header.id_length, SEEK_CUR);  // skip TARGA image comment
  524.     
  525.     if (targa_header.image_type==2) {  // Uncompressed, RGB images
  526.         for(row=rows-1; row>=0; row--) {
  527.             pixbuf = targa_rgba + row*columns*4;
  528.             for(column=0; column<columns; column++) {
  529.                 unsigned char red,green,blue,alphabyte;
  530.                 switch (targa_header.pixel_size) {
  531.                     case 24:
  532.                             
  533.                             blue = getc(fin);
  534.                             green = getc(fin);
  535.                             red = getc(fin);
  536.                             *pixbuf++ = red;
  537.                             *pixbuf++ = green;
  538.                             *pixbuf++ = blue;
  539.                             *pixbuf++ = 255;
  540.                             break;
  541.                     case 32:
  542.                             blue = getc(fin);
  543.                             green = getc(fin);
  544.                             red = getc(fin);
  545.                             alphabyte = getc(fin);
  546.                             *pixbuf++ = red;
  547.                             *pixbuf++ = green;
  548.                             *pixbuf++ = blue;
  549.                             *pixbuf++ = alphabyte;
  550.                             break;
  551.                 }
  552.             }
  553.         }
  554.     }
  555.     else if (targa_header.image_type==10) {   // Runlength encoded RGB images
  556.         unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
  557.         for(row=rows-1; row>=0; row--) {
  558.             pixbuf = targa_rgba + row*columns*4;
  559.             for(column=0; column<columns; ) {
  560.                 packetHeader=getc(fin);
  561.                 packetSize = 1 + (packetHeader & 0x7f);
  562.                 if (packetHeader & 0x80) {        // run-length packet
  563.                     switch (targa_header.pixel_size) {
  564.                         case 24:
  565.                                 blue = getc(fin);
  566.                                 green = getc(fin);
  567.                                 red = getc(fin);
  568.                                 alphabyte = 255;
  569.                                 break;
  570.                         case 32:
  571.                                 blue = getc(fin);
  572.                                 green = getc(fin);
  573.                                 red = getc(fin);
  574.                                 alphabyte = getc(fin);
  575.                                 break;
  576.                     }
  577.     
  578.                     for(j=0;j<packetSize;j++) {
  579.                         *pixbuf++=red;
  580.                         *pixbuf++=green;
  581.                         *pixbuf++=blue;
  582.                         *pixbuf++=alphabyte;
  583.                         column++;
  584.                         if (column==columns) { // run spans across rows
  585.                             column=0;
  586.                             if (row>0)
  587.                                 row--;
  588.                             else
  589.                                 goto breakOut;
  590.                             pixbuf = targa_rgba + row*columns*4;
  591.                         }
  592.                     }
  593.                 }
  594.                 else {                            // non run-length packet
  595.                     for(j=0;j<packetSize;j++) {
  596.                         switch (targa_header.pixel_size) {
  597.                             case 24:
  598.                                     blue = getc(fin);
  599.                                     green = getc(fin);
  600.                                     red = getc(fin);
  601.                                     *pixbuf++ = red;
  602.                                     *pixbuf++ = green;
  603.                                     *pixbuf++ = blue;
  604.                                     *pixbuf++ = 255;
  605.                                     break;
  606.                             case 32:
  607.                                     blue = getc(fin);
  608.                                     green = getc(fin);
  609.                                     red = getc(fin);
  610.                                     alphabyte = getc(fin);
  611.                                     *pixbuf++ = red;
  612.                                     *pixbuf++ = green;
  613.                                     *pixbuf++ = blue;
  614.                                     *pixbuf++ = alphabyte;
  615.                                     break;
  616.                         }
  617.                         column++;
  618.                         if (column==columns) { // pixel packet run spans across rows
  619.                             column=0;
  620.                             if (row>0)
  621.                                 row--;
  622.                             else
  623.                                 goto breakOut;
  624.                             pixbuf = targa_rgba + row*columns*4;
  625.                         }                        
  626.                     }
  627.                 }
  628.             }
  629.             breakOut:;
  630.         }
  631.     }
  632.     
  633.     fclose(fin);
  634. }
  635.  
  636. /*
  637. ==================
  638. R_LoadSkys
  639. ==================
  640. */
  641. char    *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
  642. void R_LoadSkys (void)
  643. {
  644.     int        i;
  645.     FILE    *f;
  646.     char    name[64];
  647.  
  648.     for (i=0 ; i<6 ; i++)
  649.     {
  650.         GL_Bind (SKY_TEX + i);
  651.         sprintf (name, "gfx/env/bkgtst%s.tga", suf[i]);
  652.         COM_FOpenFile (name, &f);
  653.         if (!f)
  654.         {
  655.             Con_Printf ("Couldn't load %s\n", name);
  656.             continue;
  657.         }
  658.         LoadTGA (f);
  659. //        LoadPCX (f);
  660.  
  661.         glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, targa_rgba);
  662. //        glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, pcx_rgb);
  663.  
  664.         free (targa_rgba);
  665. //        free (pcx_rgb);
  666.  
  667.         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  668.         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  669.     }
  670. }
  671.  
  672.  
  673. vec3_t    skyclip[6] = {
  674.     {1,1,0},
  675.     {1,-1,0},
  676.     {0,-1,1},
  677.     {0,1,1},
  678.     {1,0,1},
  679.     {-1,0,1} 
  680. };
  681. int    c_sky;
  682.  
  683. // 1 = s, 2 = t, 3 = 2048
  684. int    st_to_vec[6][3] =
  685. {
  686.     {3,-1,2},
  687.     {-3,1,2},
  688.  
  689.     {1,3,2},
  690.     {-1,-3,2},
  691.  
  692.     {-2,-1,3},        // 0 degrees yaw, look straight up
  693.     {2,-1,-3}        // look straight down
  694.  
  695. //    {-1,2,3},
  696. //    {1,2,-3}
  697. };
  698.  
  699. // s = [0]/[2], t = [1]/[2]
  700. int    vec_to_st[6][3] =
  701. {
  702.     {-2,3,1},
  703.     {2,3,-1},
  704.  
  705.     {1,3,2},
  706.     {-1,3,-2},
  707.  
  708.     {-2,-1,3},
  709.     {-2,1,-3}
  710.  
  711. //    {-1,2,3},
  712. //    {1,2,-3}
  713. };
  714.  
  715. float    skymins[2][6], skymaxs[2][6];
  716.  
  717. void DrawSkyPolygon (int nump, vec3_t vecs)
  718. {
  719.     int        i,j;
  720.     vec3_t    v, av;
  721.     float    s, t, dv;
  722.     int        axis;
  723.     float    *vp;
  724.  
  725.     c_sky++;
  726. #if 0
  727. glBegin (GL_POLYGON);
  728. for (i=0 ; i<nump ; i++, vecs+=3)
  729. {
  730.     VectorAdd(vecs, r_origin, v);
  731.     glVertex3fv (v);
  732. }
  733. glEnd();
  734. return;
  735. #endif
  736.     // decide which face it maps to
  737.     VectorCopy (vec3_origin, v);
  738.     for (i=0, vp=vecs ; i<nump ; i++, vp+=3)
  739.     {
  740.         VectorAdd (vp, v, v);
  741.     }
  742.     av[0] = fabs(v[0]);
  743.     av[1] = fabs(v[1]);
  744.     av[2] = fabs(v[2]);
  745.     if (av[0] > av[1] && av[0] > av[2])
  746.     {
  747.         if (v[0] < 0)
  748.             axis = 1;
  749.         else
  750.             axis = 0;
  751.     }
  752.     else if (av[1] > av[2] && av[1] > av[0])
  753.     {
  754.         if (v[1] < 0)
  755.             axis = 3;
  756.         else
  757.             axis = 2;
  758.     }
  759.     else
  760.     {
  761.         if (v[2] < 0)
  762.             axis = 5;
  763.         else
  764.             axis = 4;
  765.     }
  766.  
  767.     // project new texture coords
  768.     for (i=0 ; i<nump ; i++, vecs+=3)
  769.     {
  770.         j = vec_to_st[axis][2];
  771.         if (j > 0)
  772.             dv = vecs[j - 1];
  773.         else
  774.             dv = -vecs[-j - 1];
  775.  
  776.         j = vec_to_st[axis][0];
  777.         if (j < 0)
  778.             s = -vecs[-j -1] / dv;
  779.         else
  780.             s = vecs[j-1] / dv;
  781.         j = vec_to_st[axis][1];
  782.         if (j < 0)
  783.             t = -vecs[-j -1] / dv;
  784.         else
  785.             t = vecs[j-1] / dv;
  786.  
  787.         if (s < skymins[0][axis])
  788.             skymins[0][axis] = s;
  789.         if (t < skymins[1][axis])
  790.             skymins[1][axis] = t;
  791.         if (s > skymaxs[0][axis])
  792.             skymaxs[0][axis] = s;
  793.         if (t > skymaxs[1][axis])
  794.             skymaxs[1][axis] = t;
  795.     }
  796. }
  797.  
  798. #define    MAX_CLIP_VERTS    64
  799. void ClipSkyPolygon (int nump, vec3_t vecs, int stage)
  800. {
  801.     float    *norm;
  802.     float    *v;
  803.     qboolean    front, back;
  804.     float    d, e;
  805.     float    dists[MAX_CLIP_VERTS];
  806.     int        sides[MAX_CLIP_VERTS];
  807.     vec3_t    newv[2][MAX_CLIP_VERTS];
  808.     int        newc[2];
  809.     int        i, j;
  810.  
  811.     if (nump > MAX_CLIP_VERTS-2)
  812.         Sys_Error ("ClipSkyPolygon: MAX_CLIP_VERTS");
  813.     if (stage == 6)
  814.     {    // fully clipped, so draw it
  815.         DrawSkyPolygon (nump, vecs);
  816.         return;
  817.     }
  818.  
  819.     front = back = false;
  820.     norm = skyclip[stage];
  821.     for (i=0, v = vecs ; i<nump ; i++, v+=3)
  822.     {
  823.         d = DotProduct (v, norm);
  824.         if (d > ON_EPSILON)
  825.         {
  826.             front = true;
  827.             sides[i] = SIDE_FRONT;
  828.         }
  829.         else if (d < ON_EPSILON)
  830.         {
  831.             back = true;
  832.             sides[i] = SIDE_BACK;
  833.         }
  834.         else
  835.             sides[i] = SIDE_ON;
  836.         dists[i] = d;
  837.     }
  838.  
  839.     if (!front || !back)
  840.     {    // not clipped
  841.         ClipSkyPolygon (nump, vecs, stage+1);
  842.         return;
  843.     }
  844.  
  845.     // clip it
  846.     sides[i] = sides[0];
  847.     dists[i] = dists[0];
  848.     VectorCopy (vecs, (vecs+(i*3)) );
  849.     newc[0] = newc[1] = 0;
  850.  
  851.     for (i=0, v = vecs ; i<nump ; i++, v+=3)
  852.     {
  853.         switch (sides[i])
  854.         {
  855.         case SIDE_FRONT:
  856.             VectorCopy (v, newv[0][newc[0]]);
  857.             newc[0]++;
  858.             break;
  859.         case SIDE_BACK:
  860.             VectorCopy (v, newv[1][newc[1]]);
  861.             newc[1]++;
  862.             break;
  863.         case SIDE_ON:
  864.             VectorCopy (v, newv[0][newc[0]]);
  865.             newc[0]++;
  866.             VectorCopy (v, newv[1][newc[1]]);
  867.             newc[1]++;
  868.             break;
  869.         }
  870.  
  871.         if (sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
  872.             continue;
  873.  
  874.         d = dists[i] / (dists[i] - dists[i+1]);
  875.         for (j=0 ; j<3 ; j++)
  876.         {
  877.             e = v[j] + d*(v[j+3] - v[j]);
  878.             newv[0][newc[0]][j] = e;
  879.             newv[1][newc[1]][j] = e;
  880.         }
  881.         newc[0]++;
  882.         newc[1]++;
  883.     }
  884.  
  885.     // continue
  886.     ClipSkyPolygon (newc[0], newv[0][0], stage+1);
  887.     ClipSkyPolygon (newc[1], newv[1][0], stage+1);
  888. }
  889.  
  890. /*
  891. =================
  892. R_DrawSkyChain
  893. =================
  894. */
  895. void R_DrawSkyChain (msurface_t *s)
  896. {
  897.     msurface_t    *fa;
  898.  
  899.     int        i;
  900.     vec3_t    verts[MAX_CLIP_VERTS];
  901.     glpoly_t    *p;
  902.  
  903.     c_sky = 0;
  904.     GL_Bind(solidskytexture);
  905.  
  906.     // calculate vertex values for sky box
  907.  
  908.     for (fa=s ; fa ; fa=fa->texturechain)
  909.     {
  910.         for (p=fa->polys ; p ; p=p->next)
  911.         {
  912.             for (i=0 ; i<p->numverts ; i++)
  913.             {
  914.                 VectorSubtract (p->verts[i], r_origin, verts[i]);
  915.             }
  916.             ClipSkyPolygon (p->numverts, verts[0], 0);
  917.         }
  918.     }
  919. }
  920.  
  921.  
  922. /*
  923. ==============
  924. R_ClearSkyBox
  925. ==============
  926. */
  927. void R_ClearSkyBox (void)
  928. {
  929.     int        i;
  930.  
  931.     for (i=0 ; i<6 ; i++)
  932.     {
  933.         skymins[0][i] = skymins[1][i] = 9999;
  934.         skymaxs[0][i] = skymaxs[1][i] = -9999;
  935.     }
  936. }
  937.  
  938.  
  939. void MakeSkyVec (float s, float t, int axis)
  940. {
  941.     vec3_t        v, b;
  942.     int            j, k;
  943.  
  944.     b[0] = s*2048;
  945.     b[1] = t*2048;
  946.     b[2] = 2048;
  947.  
  948.     for (j=0 ; j<3 ; j++)
  949.     {
  950.         k = st_to_vec[axis][j];
  951.         if (k < 0)
  952.             v[j] = -b[-k - 1];
  953.         else
  954.             v[j] = b[k - 1];
  955.         v[j] += r_origin[j];
  956.     }
  957.  
  958.     // avoid bilerp seam
  959.     s = (s+1)*0.5;
  960.     t = (t+1)*0.5;
  961.  
  962.     if (s < 1.0/512)
  963.         s = 1.0/512;
  964.     else if (s > 511.0/512)
  965.         s = 511.0/512;
  966.     if (t < 1.0/512)
  967.         t = 1.0/512;
  968.     else if (t > 511.0/512)
  969.         t = 511.0/512;
  970.  
  971.     t = 1.0 - t;
  972.     glTexCoord2f (s, t);
  973.     glVertex3fv (v);
  974. }
  975.  
  976. /*
  977. ==============
  978. R_DrawSkyBox
  979. ==============
  980. */
  981. int    skytexorder[6] = {0,2,1,3,4,5};
  982. void R_DrawSkyBox (void)
  983. {
  984.     int        i, j, k;
  985.     vec3_t    v;
  986.     float    s, t;
  987.  
  988. #if 0
  989. glEnable (GL_BLEND);
  990. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  991. glColor4f (1,1,1,0.5);
  992. glDisable (GL_DEPTH_TEST);
  993. #endif
  994.     for (i=0 ; i<6 ; i++)
  995.     {
  996.         if (skymins[0][i] >= skymaxs[0][i]
  997.         || skymins[1][i] >= skymaxs[1][i])
  998.             continue;
  999.  
  1000.         GL_Bind (SKY_TEX+skytexorder[i]);
  1001. #if 0
  1002. skymins[0][i] = -1;
  1003. skymins[1][i] = -1;
  1004. skymaxs[0][i] = 1;
  1005. skymaxs[1][i] = 1;
  1006. #endif
  1007.         glBegin (GL_QUADS);
  1008.         MakeSkyVec (skymins[0][i], skymins[1][i], i);
  1009.         MakeSkyVec (skymins[0][i], skymaxs[1][i], i);
  1010.         MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i);
  1011.         MakeSkyVec (skymaxs[0][i], skymins[1][i], i);
  1012.         glEnd ();
  1013.     }
  1014. #if 0
  1015. glDisable (GL_BLEND);
  1016. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  1017. glColor4f (1,1,1,0.5);
  1018. glEnable (GL_DEPTH_TEST);
  1019. #endif
  1020. }
  1021.  
  1022.  
  1023. #endif
  1024.  
  1025. //===============================================================
  1026.  
  1027. /*
  1028. =============
  1029. R_InitSky
  1030.  
  1031. A sky texture is 256*128, with the right side being a masked overlay
  1032. ==============
  1033. */
  1034. void R_InitSky (texture_t *mt)
  1035. {
  1036.     int            i, j, p;
  1037.     byte        *src;
  1038.     unsigned    trans[128*128];
  1039.     unsigned    transpix;
  1040.     int            r, g, b;
  1041.     unsigned    *rgba;
  1042.     extern    int            skytexturenum;
  1043.  
  1044.     src = (byte *)mt + mt->offsets[0];
  1045.  
  1046.     // make an average value for the back to avoid
  1047.     // a fringe on the top level
  1048.  
  1049.     r = g = b = 0;
  1050.     for (i=0 ; i<128 ; i++)
  1051.         for (j=0 ; j<128 ; j++)
  1052.         {
  1053.             p = src[i*256 + j + 128];
  1054.             rgba = &d_8to24table[p];
  1055.             trans[(i*128) + j] = *rgba;
  1056.             r += ((byte *)rgba)[0];
  1057.             g += ((byte *)rgba)[1];
  1058.             b += ((byte *)rgba)[2];
  1059.         }
  1060.  
  1061.     ((byte *)&transpix)[0] = r/(128*128);
  1062.     ((byte *)&transpix)[1] = g/(128*128);
  1063.     ((byte *)&transpix)[2] = b/(128*128);
  1064.     ((byte *)&transpix)[3] = 0;
  1065.  
  1066.  
  1067.     if (!solidskytexture)
  1068.         solidskytexture = texture_extension_number++;
  1069.     GL_Bind (solidskytexture );
  1070.     glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  1071.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1072.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1073.  
  1074.  
  1075.     for (i=0 ; i<128 ; i++)
  1076.         for (j=0 ; j<128 ; j++)
  1077.         {
  1078.             p = src[i*256 + j];
  1079.             if (p == 0)
  1080.                 trans[(i*128) + j] = transpix;
  1081.             else
  1082.                 trans[(i*128) + j] = d_8to24table[p];
  1083.         }
  1084.  
  1085.     if (!alphaskytexture)
  1086.         alphaskytexture = texture_extension_number++;
  1087.     GL_Bind(alphaskytexture);
  1088.     glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  1089.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1090.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1091. }
  1092.  
  1093.